#include<linux/module.h>
#include<linux/init.h>
#include<linux/fs.h>
#include<asm/uaccess.h>
#include<asm/device.h>
#include<linux/device.h>
#include<linux/cdev.h>

MODULE_LICENSE("GPL");

#define DEVICE_NAME1 "CDEV_ZHU1"
#define DEVICE_NAME2 "CDEV_ZHU2"
#define DEVICE_NAME3 "CDEV_ZHU3"

static struct class *cdev_class;

static ssize_t globalvar_read(struct file *,char *,size_t ,loff_t *);
static ssize_t globalvar_write(struct file *,const char *,size_t ,loff_t *);

struct file_operations globalvar_fops =
{
.read =globalvar_read,
.write=globalvar_write,
};
static int global_var=0;
dev_t dev=0;
struct cdev dev_c;

static int __init globalvar_init(void)
{
	int ret,err;
	ret=alloc_chrdev_region(&dev,0,1,DEVICE_NAME3);
	if(ret)
	{
		printk("globalvar register failure\n");
		unregister_chrdev_region(dev,1);
		return ret;
	}
	else{
		printk("globalvar register sucess%d\n",dev);
	}

	cdev_init(&dev_c,&globalvar_fops);
	err=cdev_add(&dev_c,dev,1);
	if(err)
	{
		printk(KERN_NOTICE"error %d adding FC_dev\n",err);
		unregister_chrdev_region(dev,1);
	}

	cdev_class=class_create(THIS_MODULE,DEVICE_NAME2);
	device_create(cdev_class,NULL,dev,0,DEVICE_NAME1);
	return ret;
}
static void __exit globalvar_exit(void)
{
	device_destroy(cdev_class,dev);
	class_destroy(cdev_class);
	unregister_chrdev_region(dev,1);
	printk("globalvar_exit\n");
}
static ssize_t globalvar_read(struct file *filp,char *buf,size_t len,loff_t *off)
{
	if(copy_to_user(buf,&global_var,sizeof(int)))
	{
		return EFAULT;
	}
	return sizeof(int);
}
static ssize_t globalvar_write(struct file *filp,const char *buf,size_t len,loff_t *off)
{
	if(copy_from_user(&global_var,buf,sizeof(int)))
	{
		return -EFAULT;
	}
	return sizeof(int);
}
module_init(globalvar_init);
module_exit(globalvar_exit);
